package conMgr.model;

import java.util.Observable;

import conMgr.util.ObservableList;

public class Paper extends Observable
{
	/**
	 * The name of paper.
	 */
	private String name;
	
	/**
	 * The paper abstract.
	 */
	private String paperAbstract;
	
	/**
	 * The status of this paper
	 */
	private Status status;
	
	/**
	 * The category of this paper.
	 */
	private String categories;
	
	/**
	 * The keyword of this paper.
	 */
	private String keywords;
	
	/**
	 * The author of this paper.
	 */
	private User author;
	
	/**
	 * The subprogram chair assigned to this paper. This value may be null if
	 * the paper hasn't yet been assigned.
	 */
	private User subprogramChair;
	
	/**
	 * The paper.
	 */
	private Paper my_paper;
	
	/**
	 * The conference.
	 */
	private Conference conference;
	
	/**
	 * The subprogram chair's rating.
	 */
	private Integer spChairRating;
	
	/**
	 * The subprogram chair's recommendation.
	 */
	private String spChairRationale;
	
	private String docText;
	
	/**
	 * The list of reviews for the paper.
	 */
	private ObservableList<Review> listOfPaperReviews = new ObservableList<Review>();
	
	/**
	 * Constructor for the paper.
	 * @param title
	 * @param author
	 * @param conference
	 * @param paperAbstract
	 * @param categories
	 * @param keywords
	 */
	public Paper(String title, User author, Conference conference,
			String paperAbstract, String categories, String keywords, String docText)
	{
		name = title;
		this.author = author;
		this.conference = conference;
		this.paperAbstract = paperAbstract;
		this.categories = categories;
		this.keywords = keywords;
		this.docText = docText;
		this.status = Status.UNDECIDED;
		
		author.getAuthorPapers().add(this);
		conference.getPapers().add(this);
	}
	
	/**
	 * Returns a current paper.
	 * @return my_paper
	 */
	public Paper getCurrentPaper()
	{
		return my_paper;
	}
	
	/**
	 * Returns paper's title.
	 * @return paper's name
	 */
	public String getTitle()
	{
		return this.name;
	}
	
	/**
	 * Returns a paper's author.
	 * @return author of the paper.
	 */
	public User getAuthor()
	{	
		return this.author;
	}
	
	/**
	 * Returns a conference for this paper.
	 * @return conference for this paper.
	 */
	public Conference getConference()
	{
		return this.conference;
	}
	
	/**
	 * Returns a category for this paper.
	 * @return categories for this paper.
	 */
	public String getCategories()
	{
		return this.categories;
	}
	
	/**
	 * Returns keywords for this paper.
	 * @return keywords for this paper
	 */
	public String getKeywords()
	{
		return this.keywords;
	}
	
	public String getDocText()
	{
		return this.docText;
	}
	
	public void setDocText(String docText)
	{
		this.docText = docText;
	}
	
	/**
	 * Returns paper's status.
	 * @return status for this paper.
	 */
	public Status getStatus()
	{
		return this.status;
	}
	
	/**
	 * Returns a paper's abstract.
	 * @return abstract for this paper.
	 */
	public String getPaperAbstract()
	{
		return this.paperAbstract;
	}
	
	/**
	 * 
	 * @return subprogram chair user.
	 */
	public User getSubprogramChair()
	{
		return subprogramChair;
	}
	
	/**
	 * Returns a SubprogramChair's rating.
	 * @return SubprogramChair's rating.
	 */
	public Integer getSubprogramChairRating()
	{
		return this.spChairRating;
	}
	
	/**
	 * Returns a SubprogramChair's rationale.
	 * @return SubprogramChair's rationale.
	 */
	public String getSubprogramChairRationale()
	{
		return this.spChairRationale;
	}
	
	/**
	 * Marks the paper as accepted.
	 */
	public void accept()
	{
		this.status = Status.ACCEPTED;
		setChanged();
		notifyObservers();
	}
	
	/**
	 * Marks the paper as rejected.
	 */
	public void reject()
	{
		this.status = Status.REJECTED;
		setChanged();
		notifyObservers();
	}
	
	/**
	 * Allows to user remove his paper.
	 */
	public void rescind()
	{
		my_paper = null;
		setChanged();
		notifyObservers();
	}
	
	/**
	 * Marks the paper as undecided.
	 */
	public void undecided()
	{
		this.status = Status.UNDECIDED;
		setChanged();
		notifyObservers();
	}
	
	/**
	 * Allows to user revise his paper.
	 * @param title
	 * @param categories
	 * @param keywords
	 */
	public void revise(String title, String categories, String keywords)
	{
		this.name = title;
		this.categories = categories;
		this.keywords = keywords;	
		setChanged();
		notifyObservers();
	}
	
	/**
	 * Assigns subprogram chair for this paper.
	 * @param subprogramChair
	 */
	public void assignSubprogramChair(User subprogramChair)
	{
		this.subprogramChair = subprogramChair;
		setChanged();
		notifyObservers();
	}
	
	/**
	 * Submits to program chair the subprogram chair's rating and rationale.	 *  .
	 * @param rating
	 * @param rationale
	 */
	public void submitToProgramChair(Integer rating, String rationale)
	{
		this.status = Status.RECOMMENDED;
		spChairRating = rating;
		spChairRationale = rationale;
		setChanged();
		notifyObservers();
	}
	
    /**
     * Returns the list of the reviews for this paper.
     * @return list of reviews.
     */
	public ObservableList<Review> getPaperReviews()
	{
		return listOfPaperReviews;
	}
}
